package com.alageek.crowd.mvc.handler;

import com.alageek.crowd.constant.CrowdConstant;
import com.alageek.crowd.entity.Admin;
import com.alageek.crowd.exception.AdminAddFailedException;
import com.alageek.crowd.exception.AdminEditFailedException;
import com.alageek.crowd.exception.LoginFailedException;
import com.alageek.crowd.service.api.AdminService;
import com.alageek.crowd.util.CrowdUtil;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author alageek
 */
@Controller
@RequestMapping("/admin")
public class AdminHandler {

    private final AdminService adminService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public AdminHandler(AdminService adminService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.adminService = adminService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    //获取Logger对象，所传class是当前打印日志的类
    private final Logger logger = LoggerFactory.getLogger(AdminHandler.class);

    @RequestMapping("/do/edit.html")
    public String edit(Admin admin, Integer pageNum, String keyword){
        if("".equals(admin.getLoginAcct())
                ||"".equals(admin.getUserName())
                ||"".equals(admin.getEmail())){
            throw new AdminEditFailedException(CrowdConstant.MESSAGE_FORM_NOT_FULL);
        }
        logger.info(admin.toString());
        try{
            adminService.update(admin);
        } catch (Exception e){
            e.printStackTrace();
            throw new AdminEditFailedException(CrowdConstant.MESSAGE_UPDATE_ERROR);
        }
        return "redirect:/admin/get/page.html?pageNum=" + pageNum + "&keyword=" + keyword;
    }

    @PreAuthorize("hasAuthority('user:add')")
    @RequestMapping("/do/add.html")
    public String save(Admin admin){
        if("".equals(admin.getLoginAcct())
                ||"".equals(admin.getUserPswd())
                ||"".equals(admin.getUserName())
                ||"".equals(admin.getEmail())){
            throw new AdminAddFailedException(CrowdConstant.MESSAGE_FORM_NOT_FULL);
        }
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = simpleDateFormat.format(date);
        admin.setCreateTime(createTime);
        //String userPswd = CrowdUtil.encryptMd5(admin.getUserPswd());
        String userPswd = bCryptPasswordEncoder.encode(admin.getUserPswd());
        admin.setUserPswd(userPswd);
        logger.info(admin.toString());
        try{
            adminService.saveAdmin(admin);
        } catch (Exception e){
            e.printStackTrace();
            if(e instanceof DuplicateKeyException){
                throw new AdminAddFailedException(CrowdConstant.MESSAGE_LOGINACCT_DUPLICATE);
            }
            throw e;
        }
        return "redirect:/admin/get/page.html?pageNum=" + Integer.MAX_VALUE;
    }

    @RequestMapping("/remove/{adminId}.html")
    public String remove(
            @PathVariable("adminId") Integer adminId,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("keyword") String keyword){
        adminService.remove(adminId);
        return "redirect:/admin/get/page.html?pageNum=" + pageNum + "&keyword=" + keyword;
    }

    @RequestMapping("/get/page.html")
    public String getAdminPage(
            @RequestParam(value = "keyword", defaultValue = "") String keyword,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            ModelMap modelMap){
        PageInfo<Admin> pageInfo = adminService.getAdminPage(keyword,pageNum,pageSize);
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
        return "admin-page";
    }

    @RequestMapping("/do/login.html")
    public String doLogin(
            @RequestParam("loginAcct") String loginAcct,
            @RequestParam("userPswd") String userPswd,
            HttpSession httpSession){
        if("".equals(loginAcct) || "".equals(userPswd)){
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        List<Admin> list = adminService.getAdmin(new Admin(loginAcct, CrowdUtil.encryptMd5(userPswd)));
        if(list == null || list.size() == CrowdConstant.ZERO || list.get(0) == null){
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        httpSession.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, list.get(0));
        return "redirect:/admin/to/main/page.html";
    }

    @RequestMapping("/do/logout.html")
    public String doLogout(HttpSession httpSession){
        httpSession.invalidate();
        return "redirect:/admin/to/login/page.html";
    }

}
